/*********************
* Author:Dzlua
* QQ:505544956
* time:2016/08/20
*/
#include "Dialog.h"

class HandleEvent : public EventHandler
{
public:
    HandleEvent(){}
    ~HandleEvent(){}
public:
    void askClose(IWindow* wnd, bool* bClose);
    void onButtonCloseClick(Button* btn);
    void onButtonMinClick(Button* btn);
    void onButtonMaxClick(Button* btn);
    void onButtonRestoreClick(Button* btn);
    void onButtonCommonClick(Button* btn);
    void onButton1Click(Button* btn);
    void onButton2Click(Button* btn);
    void onTableLayoutSelectedChanged(TableLayout* tab, size_t idx);
    void onCheckBoxSelected(CheckBox* checkbox);
    void onOptionSelected(CheckBox* checkbox);
    void onProgressProgress(Progress* prg);
    void onSliderProgress(Slider* slider);
    void onScrollBarScroll(ScrollBar* scrollbar);
    //dialog
    void onDialogButtonCloseClick(Button* btn);
    void onDialogButtonYesClick(Button* btn);
    void onDialogButtonCancelClick(Button* btn);
    // dialog event
    void onDialogCloseClick(Dialog* dialog, void* data1, void* data2);
    void onDialogYesClick(Dialog* dialog, void* data1, void* data2);
    void onDialogCancelClick(Dialog* dialog, void* data1, void* data2);
};

void Init(IWindow* wnd, Dialog &dialog, HandleEvent &evt);

void TestLoadLayoutFromStr()
{
    IEnginePtr->LoadResFromStr("<Res><String name=\"test2\" value=\"LoadResFromStr.\"/></Res>");

    IWindow* wnd = IEnginePtr->GetWindowInterface();
    bool bOK = wnd->Create("TestLoadLayoutFromStr", "TestLoadLayoutFromStr", WINDOWPOS_CENTERED, WINDOWPOS_CENTERED, 640, 480, 0);
    if (!bOK){
        wnd->Release();
        Log("[TestLoadLayoutFromStr] : create window error.");
        return;
    }

    /*window in file/str:window will be load*/
    const char* wndxml =
        "<Window title=\"dialog\" size=\"300,480\" caption=\"0,0,0,30\">"
            "<VerticalLayout name=\"root\" color=\"dst:bk;color:#FF7F7F7F;\">"
                "<HorizontalLayout height=\"30\" color=\"dst:bk;color:#FFFFFFFF;\">"
                    "<Control size=\"17,18\" padding=\"5,6,3,0\" image=\"dst:bk;image:(img:logo;);\"/>"
                    "<Label autowidth=\"true\" font=\"sh-18\" translatetext=\"true\" text=\"warning\"/>"
                    "<Control/>"
                    "<Button name=\"close\" size=\"30,25\" statusimage=\"dst:(normal,hot,pressed);status:(img:close;size:30,25;num:3;type:v1;);\"/>"
                "</HorizontalLayout>"
                "<Label height=\"20\" fontid=\"1\" translatetext=\"true\" text=\"test2\" color=\"dst:bk;color:#FFFF0000;\"/>"
            "</VerticalLayout>"
        "</Window>";
    wnd->LoadLayoutFromStr(wndxml);

    /*control in file/str:h1 can not be build.*/
    const char* ctrlxml =
        "<HorizontalLayout name=\"h1\" color=\"dst:bk;color:#FFFF0000;\">"
        "<VerticalLayout>"
        "<HorizontalLayout name=\"h2\" color=\"dst:bk;color:#FFFF0000;\">"
        "<Label name=\"abcde\" height=\"20\" width=\"100\" fontid=\"1\" text=\"LoadControl\" color=\"dst:bk;color:#FF00FF00;\"/>"
        "</HorizontalLayout>"
        "<Include source=\"wnd/dialog.xml\"/>"
        "</VerticalLayout>"
        "</HorizontalLayout>";

    Container* cont = Container::ToContainer(wnd->FindControl("root"));
    if (cont){
        Control* ctrl = wnd->LoadControlFromStr(ctrlxml);
        if (ctrl && !cont->Add(ctrl)){
            ctrl->Release();
        }
    }

    ISurface* icon = IEnginePtr->FindSurface("logo");
    wnd->SetIcon(icon);

    wnd->ShowWindow();
}

int main(int argc, char *argv[])
{
    IEnginePtr->Init();

    //engine.SetStringGroup("Chinese");
    IEnginePtr->SetStringGroup("English");
    // all xml(font/string/image/window/control) files's dir.
    IEnginePtr->SetXmlDir("test/test1/xml/");

    /* if no IEngine::SetXmlDir or IEngine::SetXmlDir(0),
            engine.LoadRes("res/res.xml") : engine._LoadRes("res/res.xml")
       else engine.SetXmlDir("edui_sdl/test/test2/xml/");
            engine.LoadRes("res/res.xml") : engine._("edui_sdl/test/test2/xml/res/res.xml")
    */
    if (!IEnginePtr->LoadRes("res/res.xml")){
        Log("[main] : load res error.");
    } else {
        IWindow* wnd = IEnginePtr->GetWindowInterface();
        bool bOK = wnd->Create("main", "main", WINDOWPOS_CENTERED, WINDOWPOS_CENTERED, 640, 480, WINDOW_BORDERLESS);
        if (!bOK){
            wnd->Release();
            Log("[main] : create window error.");
        } else if (!wnd->LoadLayout("wnd/main.xml")){
            Log("[main] : load window layout error.");
        } else {

            TestLoadLayoutFromStr();

            Dialog dialog;

            HandleEvent evt;
            wnd->evt.askClose.connect(&evt, &HandleEvent::askClose);

            Init(wnd, dialog, evt);

            wnd->ShowWindow();

            IEnginePtr->RunMsgLoop(-1);
        }
    }

    IEnginePtr->Quit();
    return 0;
}

void Init(IWindow* wnd, Dialog &dialog, HandleEvent &evt)
{
    ISurface* icon = IEnginePtr->FindSurface("logo");
    wnd->SetIcon(icon);

    Button* button = Button::ToButton(wnd->FindControl("min"));
    if (button){
        button->evt.click.connect(&evt, &HandleEvent::onButtonMinClick);
    }

    button = Button::ToButton(wnd->FindControl("max"));
    if (button){
        button->evt.click.connect(&evt, &HandleEvent::onButtonMaxClick);
    }

    button = Button::ToButton(wnd->FindControl("restore"));
    if (button){
        button->evt.click.connect(&evt, &HandleEvent::onButtonRestoreClick);
    }

    button = Button::ToButton(wnd->FindControl("close"));
    if (button){
        button->evt.click.connect(&evt, &HandleEvent::onButtonCloseClick);
    }

    button = Button::ToButton(wnd->FindControl("button1"));
    if (button){
        button->evt.click.connect(&evt, &HandleEvent::onButton1Click);
    }

    button = Button::ToButton(wnd->FindControl("button2"));
    if (button){
        button->evt.click.connect(&evt, &HandleEvent::onButton2Click);
    }

    TableLayout* tab = TableLayout::ToTableLayout(wnd->FindControl("tableLayout"));
    if (tab){
        tab->evt.selectedChanged.connect(&evt, &HandleEvent::onTableLayoutSelectedChanged);
    }

    CheckBox* checkbox = CheckBox::ToCheckBox(wnd->FindControl("checkbox"));
    if (checkbox){
        checkbox->evt.selected.connect(&evt, &HandleEvent::onCheckBoxSelected);
    }
    checkbox = CheckBox::ToCheckBox(wnd->FindControl("checkbox1"));
    if (checkbox){
        checkbox->evt.selected.connect(&evt, &HandleEvent::onCheckBoxSelected);
    }
    checkbox = CheckBox::ToCheckBox(wnd->FindControl("checkbox2"));
    if (checkbox){
        checkbox->evt.selected.connect(&evt, &HandleEvent::onCheckBoxSelected);
    }
    checkbox = CheckBox::ToCheckBox(wnd->FindControl("checkbox3"));
    if (checkbox){
        checkbox->evt.selected.connect(&evt, &HandleEvent::onCheckBoxSelected);
    }
    checkbox = CheckBox::ToCheckBox(wnd->FindControl("checkbox4"));
    if (checkbox){
        checkbox->evt.selected.connect(&evt, &HandleEvent::onCheckBoxSelected);
    }

    CheckBox* option = CheckBox::ToCheckBox(wnd->FindControl("option"));
    if (option){
        option->evt.selected.connect(&evt, &HandleEvent::onOptionSelected);
    }
    option = CheckBox::ToCheckBox(wnd->FindControl("option1"));
    if (option){
        option->evt.selected.connect(&evt, &HandleEvent::onOptionSelected);
    }
    option = CheckBox::ToCheckBox(wnd->FindControl("option2"));
    if (option){
        option->evt.selected.connect(&evt, &HandleEvent::onOptionSelected);
    }

    button = Button::ToButton(wnd->FindControl("prgErase"));
    if (button){
        button->evt.click.connect(&evt, &HandleEvent::onButtonCommonClick);
    }

    button = Button::ToButton(wnd->FindControl("prgAdd"));
    if (button){
        button->evt.click.connect(&evt, &HandleEvent::onButtonCommonClick);
    }

    button = Button::ToButton(wnd->FindControl("prgErase1"));
    if (button){
        button->evt.click.connect(&evt, &HandleEvent::onButtonCommonClick);
    }

    button = Button::ToButton(wnd->FindControl("prgAdd1"));
    if (button){
        button->evt.click.connect(&evt, &HandleEvent::onButtonCommonClick);
    }

    Progress* progress = Progress::ToProgress(wnd->FindControl("progress"));
    if (progress){
        progress->evt.progress.connect(&evt, &HandleEvent::onProgressProgress);
    }

    progress = Progress::ToProgress(wnd->FindControl("progress1"));
    if (progress){
        progress->evt.progress.connect(&evt, &HandleEvent::onProgressProgress);
    }

    Slider* slider = Slider::ToSlider(wnd->FindControl("slider1"));
    if (slider){
        slider->evt.progress.connect(&evt, &HandleEvent::onSliderProgress);
    }

    ScrollBar* scrollbar = ScrollBar::ToScrollBar(wnd->FindControl("scrollbar1"));
    if (scrollbar){
        scrollbar->evt.scroll.connect(&evt, &HandleEvent::onScrollBarScroll);
    }

    //dialog
    button = Button::ToButton(wnd->FindControl("dclose"));
    if (button){
        button->evt.click.connect(&evt, &HandleEvent::onDialogButtonCloseClick);
    }
    button = Button::ToButton(wnd->FindControl("dyes"));
    if (button){
        button->evt.click.connect(&evt, &HandleEvent::onDialogButtonYesClick);
    }
    button = Button::ToButton(wnd->FindControl("dcancel"));
    if (button){
        button->evt.click.connect(&evt, &HandleEvent::onDialogButtonCancelClick);
    }

    dialog.evt.close.connect(&evt, &HandleEvent::onDialogCloseClick);
    dialog.evt.yes.connect(&evt, &HandleEvent::onDialogYesClick);
    dialog.evt.cancel.connect(&evt, &HandleEvent::onDialogCancelClick);

    wnd->SetUserData("dialog", &dialog);
}

//-------------------------//
void HandleEvent::askClose(IWindow* wnd, bool* bClose)
{
    *bClose = false;

    Dialog* dialog = (Dialog*)wnd->GetUserData("dialog");
    Rect rc = wnd->GetRect();

    String text = IEnginePtr->GetText("closetip", "Are you sure to close %s window?");
    //String text = IEnginePtr->GetText(1, "Are you sure to close %s window?");
    text.Format(text, wnd->GetName());

    dialog->Show(wnd, text.GetString(), rc, wnd);
}

void HandleEvent::onButtonCloseClick(Button* btn)
{
    IWindow* wnd = btn->GetWindow();
    wnd->AskClose();    
}

void HandleEvent::onButtonMinClick(Button* btn)
{
    IWindow* wnd = btn->GetWindow();
    wnd->MinWindow();
}

void HandleEvent::onButtonMaxClick(Button* btn)
{
    IWindow* wnd = btn->GetWindow();
    btn->SetVisible(false);
    Control* ctrl = wnd->FindControl("restore");
    if (ctrl){
        ctrl->SetVisible(true);
    }
    wnd->MaxWindow();
}

void HandleEvent::onButtonRestoreClick(Button* btn)
{
    IWindow* wnd = btn->GetWindow();
    btn->SetVisible(false);
    Control* ctrl = wnd->FindControl("max");
    if (ctrl){
        ctrl->SetVisible(true);
    }
    wnd->RestoreWindow();
}

void HandleEvent::onButton1Click(Button* btn)
{
    IWindow* wnd = btn->GetWindow();
    IEnginePtr->SetStringGroup("English");
    Label* label = Label::ToLabel(wnd->FindControl("text"));
    if (label){
        label->SetColor("dst:text;color:#FFFFFF00;");
    }
}

void HandleEvent::onButton2Click(Button* btn)
{
    IWindow* wnd = btn->GetWindow();
    IEnginePtr->SetStringGroup("Chinese");
    Label* label = Label::ToLabel(wnd->FindControl("text"));
    if (label){
        label->SetColor("dst:text;color:#FF00FF00;");
    }
}

void HandleEvent::onTableLayoutSelectedChanged(TableLayout* tab, size_t idx)
{
    IWindow* wnd = tab->GetWindow();
    Log("[HandleEvent] %s %s selected %d", wnd->GetName(), tab->GetName(), idx);
}

void HandleEvent::onCheckBoxSelected(CheckBox* checkbox)
{
    IWindow* wnd = checkbox->GetWindow();
    Log("[HandleEvent] %s %s selected %d", wnd->GetName(), checkbox->GetName(), checkbox->IsSelected());
    CheckBox* ctrl = CheckBox::ToCheckBox(wnd->FindControl("option1"));
    if (ctrl){
        ctrl->SetSelect(checkbox->IsSelected());
    }
}

void HandleEvent::onOptionSelected(CheckBox* checkbox)
{
    IWindow* wnd = checkbox->GetWindow();
    Log("[HandleEvent] %s %s selected %d", wnd->GetName(), checkbox->GetName(), checkbox->IsSelected());
}

void HandleEvent::onButtonCommonClick(Button* btn)
{
    IWindow* wnd = btn->GetWindow();
    const char* name = btn->GetName();
    if (0 == strcmp(name, "prgAdd")){
        Progress* prg = Progress::ToProgress(wnd->FindControl("progress"));
        if (prg){
            int val = prg->GetValue();
            if (prg->GetMaxValue() == val) return;
            val += 10;
            prg->SetValue(val);
            Label* label = Label::ToLabel(wnd->FindControl("progresstext"));
            if (label){
                String str;
                str.Format("%d%%", val);
                label->SetText(str.GetString());
            }
        }
    } else if (0 == strcmp(name, "prgErase")){
        Progress* prg = Progress::ToProgress(wnd->FindControl("progress"));
        if (prg){
            int val = prg->GetValue();
            if (prg->GetMinValue() == val) return;
            val -= 10;
            prg->SetValue(val);
            Label* label = Label::ToLabel(wnd->FindControl("progresstext"));
            if (label){
                String str;
                str.Format("%d%%", val);
                label->SetText(str.GetString());
            }
        }
    } else if (0 == strcmp(name, "prgAdd1")){
        Progress* prg = Progress::ToProgress(wnd->FindControl("progress1"));
        Progress* prg2 = Progress::ToProgress(wnd->FindControl("progress2"));
        Slider* slider = Slider::ToSlider(wnd->FindControl("slider1"));
        if (prg){
            int val = prg->GetValue();
            if (prg->GetMaxValue() == val) return;
            val += 10;
            prg->SetValue(val);
            if (prg2){
                prg2->SetValue(val);
            }
            if (slider){
                slider->SetValue(val);
            }
        }
    } else if (0 == strcmp(name, "prgErase1")){
        Progress* prg = Progress::ToProgress(wnd->FindControl("progress1"));
        Progress* prg2 = Progress::ToProgress(wnd->FindControl("progress2"));
        Slider* slider = Slider::ToSlider(wnd->FindControl("slider1"));
        if (prg){
            int val = prg->GetValue();
            if (prg->GetMinValue() == val) return;
            val -= 10;
            prg->SetValue(val);
            if (prg2){
                prg2->SetValue(val);
            }
            if (slider){
                slider->SetValue(val);
            }
        }
    }
}

void HandleEvent::onProgressProgress(Progress* prg)
{
    IWindow* wnd = prg->GetWindow();
    Log("[HandleEvent] %s %s progress:%d", wnd->GetName(), prg->GetName(), prg->GetValue());
}

void HandleEvent::onSliderProgress(Slider* slider)
{
    IWindow* wnd = slider->GetWindow();
    Log("[HandleEvent] %s %s slider:%d", wnd->GetName(), slider->GetName(), slider->GetValue());
    float opacity = slider->GetValue()/(float)(slider->GetMaxValue());
    if (opacity <= 0.1f) opacity = 0.1f;
    wnd->SetOpacity(opacity);
}

void HandleEvent::onScrollBarScroll(ScrollBar* scrollbar)
{
    IWindow* wnd = scrollbar->GetWindow();
    Log("[HandleEvent] %s %s scrollbar:%d", wnd->GetName(), scrollbar->GetName(), scrollbar->GetValue());

}

//----------------------//

void HandleEvent::onDialogButtonCloseClick(Button* btn)
{
    IWindow* wnd = btn->GetWindow();
    Control* ctrl = wnd->FindControl("dialogLayout");
    if (ctrl){
        ctrl->SetVisible(false);
    }
    wnd->Invaldate();
}

void HandleEvent::onDialogButtonYesClick(Button* btn)
{
    IWindow* wnd = btn->GetWindow();
    Control* ctrl = wnd->FindControl("dialogLayout");
    if (ctrl){
        ctrl->SetVisible(false);
    }
    wnd->Invaldate();
    wnd->Close();
}

void HandleEvent::onDialogButtonCancelClick(Button* btn)
{
    IWindow* wnd = btn->GetWindow();
    Control* ctrl = wnd->FindControl("dialogLayout");
    if (ctrl){
        ctrl->SetVisible(false);
    }
    wnd->Invaldate();
}

//----------------------//

void HandleEvent::onDialogCloseClick(Dialog* dialog, void* data1, void* data2)
{}

void HandleEvent::onDialogYesClick(Dialog* dialog, void* data1, void* data2)
{
    dialog->Close();
    IWindow* wnd = (IWindow*) data1;
    Control* ctrl = wnd->FindControl("dialogLayout");
    if (ctrl){
        ctrl->SetVisible(true);
        Label* label = Label::ToLabel(ctrl->FindControl("dtext"));
        if (label){
            String text = IEnginePtr->GetText("closetip", "Are you sure to close %s window?");
            text.Format(text, wnd->GetName());
            label->SetText(text.GetString());
        }
    }
    wnd->Invaldate();
}

void HandleEvent::onDialogCancelClick(Dialog* dialog, void* data1, void* data2)
{
    dialog->Close();
}